<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <title>RabbitMQ  &middot; sitename</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">


<meta name="description" content="RabbitMQ description" />

<meta name="keywords" content="one, two, ">


<meta property="og:title" content="RabbitMQ  &middot; sitename ">
<meta property="og:site_name" content="sitename"/>
<meta property="og:url" content="https://lvzongcheng.gitee.io/information/rabbitmq/" />
<meta property="og:locale" content="en-EN">


<meta property="og:type" content="article" />
<meta property="og:description" content="RabbitMQ description"/>
<meta property="og:article:published_time" content="2020-07-03T00:00:00Z" />
<meta property="og:article:modified_time" content="2020-07-03T00:00:00Z" />

  
    
<meta property="og:article:tag" content="one">
    
<meta property="og:article:tag" content="two">
    
  

  

<script type="application/ld+json">
  {
    "@context": "http://schema.org",
    "@type": "Article",
    "headline": "RabbitMQ",
    "author": {
      "@type": "Person",
      "name": "LvZongCheng"
    },
    "datePublished": "2020-07-03",
    "description": "RabbitMQ description",
    "wordCount":  420 
  }
</script>



<link rel="canonical" href="https://lvzongcheng.gitee.io/information/rabbitmq/" />

<link rel="apple-touch-icon-precomposed" sizes="144x144" href="https://lvzongcheng.gitee.io/touch-icon-144-precomposed.png">
<link href="https://lvzongcheng.gitee.io/favicon.png" rel="icon">

<meta name="generator" content="Hugo 0.60.0" />

  <!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

<link href='https://fonts.googleapis.com/css?family=Merriweather:300%7CRaleway%7COpen+Sans' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="/css/font-awesome.min.css">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/highlight/default.css">

  
  
	<script>
	  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
	  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
	  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
	  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

	  ga('create', 'Your Google Analytics tracking code', 'auto');
	  ga('send', 'pageview');

	</script>

</head>
<body>
  <main id="main-wrapper" class="container main_wrapper has-sidebar">
    <header id="main-header" class="container main_header">
  <div class="container brand">
  <div class="container title h1-like">
  <a class="baselink" href="https://lvzongcheng.gitee.io">
  LvZongCheng

</a>

</div>

  
<div class="container topline">
  
  淡定 执著 进取 自律


</div>


</div>

  <nav class="container nav primary no-print">
  

<a class="homelink" href="https://lvzongcheng.gitee.io">home</a>


  
<a href="https://lvzongcheng.gitee.io/framework" title="Show list of Frameworks">Frameworks</a>

<a href="https://lvzongcheng.gitee.io/java" title="Show list of Java">Java</a>

<a href="https://lvzongcheng.gitee.io/linux" title="Show list of Linux">Linux</a>

<a href="https://lvzongcheng.gitee.io/redis" title="Show list of Redis">Redis</a>

<a href="https://lvzongcheng.gitee.io/sql" title="Show list of SQL">SQL</a>

<a href="https://lvzongcheng.gitee.io/Spring" title="Show list of Spring">Spring</a>

<a href="https://lvzongcheng.gitee.io/tools" title="Show list of Tools">Tools</a>

<a href="https://lvzongcheng.gitee.io/webpage" title="Show list of WebPage">WebPage</a>

<a href="https://lvzongcheng.gitee.io/information" title="Show list of information">information</a>

<a href="https://lvzongcheng.gitee.io/network" title="Show list of network">network</a>

<a href="https://lvzongcheng.gitee.io/%E5%BE%AE%E6%9C%8D%E5%8A%A1" title="Show list of 微服务">微服务</a>

<a href="https://lvzongcheng.gitee.io/%E6%80%BB%E7%BB%93" title="Show list of 总结">总结</a>

<a href="https://lvzongcheng.gitee.io/%E6%9C%BA%E5%99%A8%E8%87%AA%E5%8A%A8%E5%8C%96" title="Show list of 机器自动化">机器自动化</a>

<a href="https://lvzongcheng.gitee.io/%E6%B1%87%E7%BC%96" title="Show list of 汇编">汇编</a>

<a href="https://lvzongcheng.gitee.io/%E8%AE%B0%E4%BA%8B%E6%9C%AC" title="Show list of 记事本">记事本</a>


</nav>

<div class="container nav secondary no-print">
  
<a id="contact-link-email" class="contact_link" rel="me" aria-label="Email" href="mailto:Lyc19880405@163.com">
  <span class="fa fa-envelope-square"></span></a>



<a id="contact-link-github" class="contact_link" rel="me" aria-label="Github" href="https://github.com/enten/hugo-boilerplate">
  <span class="fa fa-github-square"></span></a>




 


















</div>


  

</header>


<article id="main-content" class="container main_content single">
  <header class="container hat">
  <h1>RabbitMQ
</h1>

</header>

  <div class="container content">
  <h3 id="rabbitmq">RabbitMQ</h3>
<ul>
<li><a href="https://www.cnblogs.com/sgh1023/p/11217017.html">入门文档</a></li>
<li><a href="http://rabbitmq.mr-ping.com/">RabbitMQ 中文文档</a></li>
<li><a href="https://www.erlang.org/downloads">下载地址</a></li>
<li><a href="https://www.jianshu.com/p/3bad4875f43e">使用教程</a></li>
<li><a href="https://www.imooc.com/learn/1042">RabbitMQ消息中间件极速入门与实战</a></li>
<li><a href="https://www.cnblogs.com/linyufeng/p/9885645.html">RabbitMQ与SpringBoot整合</a></li>
<li><a href="https://mp.weixin.qq.com/s?__biz=MzIwMTg3NzYyOA==&amp;mid=2247483858&amp;idx=1&amp;sn=2855220277c7c0ba4c1eea7824ea1684&amp;chksm=96e670c1a191f9d7044c274552313fd46346f9192299a36841cd29c5294546335e3706d6968d&amp;token=1195735466&amp;lang=zh_CN#rd">RabbitMQ（一）Windws/Linux环境搭建（完整版）</a>
消息确认机制</li>
</ul>
<h4 id="heading">问题</h4>
<p>延迟队列和定时消息
死信队列
消息重复发送
消息失败重发</p>
<h5 id="heading1">错误处理及注意</h5>
<p>默认登录名和密码  guest guest
默认存储在磁盘中，在启动时加 &ndash;ram 存储在内存中。</p>
<p>路由与队列绑定 模糊匹配*与#的区别<br>
<code>*</code> 支持一级模糊匹配,<code>#</code> 支持多级匹配<br>
级以[.]分隔</p>
<h5 id="heading2">概念术语</h5>
<p>比较重要的概念有 4 个，分别为：<strong>虚拟主机，交换机，队列和绑定</strong></p>
<p>**虚拟主机：**一个虚拟主机持有一组交换机，队列和绑定。为什么需要多个
虚拟主机呢？很简单， RabbitMQ 当中，用户只能在虚拟主机的粒度进行
权限控制。 因此，如果需要禁止A组访问B组的交换机/队列/绑定，必须
为A和B分别创建一个虚拟主机。每一个 RabbitMQ 服务器都有一个默认的
虚拟主机。</p>
<p>**交换机:**Exchange用于转发信息,但是它不会做存储,如果每天Queue bind
到Exchange的话，它会被直接丢弃掉Producer发送过来的信息。
这里比较重要的一个概念:路由键。消息到交换机的时候，交换机会转发
到对应的队列中，那么究竟转发到哪个队列，就根据该路由键判断。</p>
<p>队列的作用在上面已经说过这里就不在说明。</p>
<p><strong>绑定:</strong> 是交换机需要和队列相绑定，这其中如上图所示，就是多对多的关系。</p>
<h5 id="rabbitmq1">RabbitMQ四种交换机路由规则介绍</h5>
<ol>
<li>
<p>Direct Exchange
处理路由键。需要将一个队列绑定到交换机上，要求该消息与一个特定的路由键完全匹配。
这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “abc”，则只有被标记
为“abc”的消息才被转发，不会转发abc.def，也不会转发dog.ghi，只会转发abc</p>
</li>
<li>
<p>Fanout Exchange
不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被
转发到与该交换机绑定的所有队列上。很像子网广播，每台子网内的主机都获得了一份复
制的消息。Fanout交换机转发消息是最快的。</p>
</li>
<li>
<p>Topic Exchange
将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个
词，符号“”匹配不多不少一个词。因此“abc.#”能够匹配到“abc.def.ghi”，但是“abc.” 
只会匹配到“abc.def”。</p>
</li>
<li>
<p>Headers Exchanges
不处理路由键。而是根据发送的消息内容中的headers属性进行匹配。在绑定Queue与Exc
hange时指定一组键值对；当消息发送到RabbitMQ时会取到该消息的headers与Exchange绑
定时指定的键值对进行匹配；如果完全匹配则消息会路由到该队列，否则不会路由到该队
列。headers属性是一个键值对，可以是Hashtable，键值对的值可以是任何类型。而fano
ut，direct，topic 的路由键都需要要字符串形式的。
匹配规则x-match有下列两种类型：</p>
<ul>
<li>x-match = all ：表示所有的键值对都匹配才能接受到消息</li>
<li>x-match = any ：表示只要有键值对匹配就能接受到消息</li>
</ul>
</li>
</ol>
<h4 id="rabbitmqspringboot">RabbitMQ与SpringBoot整合</h4>
<p><strong>RabbitTemplate中convertSendAndReceive和convertAndSend区别</strong><br>
使用 convertAndSend 方法时的结果：输出时没有顺序，不需要等待，直接运行<br>
使用 convertSendAndReceive 方法时的结果：使用此方法，只有确定消费者接收
到消息，才会发送下一条信息，每条消息之间会有间隔时间</p>
<h5 id="heading3">（一、注解方式）</h5>
<h6 id="heading4">绑定路由和队列</h6>
<pre><code>@Configuration
public class RabbitMqConfig {

    public static final String EXCHANGES = &quot;rabbit-exchanges&quot;;

    public static final String QUEUE = &quot;rabbit-queue&quot;;

	//* 支持一级模糊匹配,# 支持多级匹配,级以[.]分隔
    public static final String KEY=&quot;key.#&quot;;

    @Bean
    public Queue rabbitQueue() {
        return QueueBuilder.durable(GBAQ).build();
    }

    @Bean
    public Exchange rabbitExchange() {
		//选择路由类型
        return ExchangeBuilder.fanoutExchange(GBAE).durable(true).build();
    }

    @Bean
    public Binding gbeExchangeQueue(@Qualifier(value = &quot;rabbitQueue&quot;) Queue queue, @Qualifier(value = &quot;rabbitExchange&quot;) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(GBA_KEY).noargs();
    }
}
</code></pre><h6 id="heading5">发送消息</h6>
<pre><code>@Component
public class RabbitMqPublisher {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void publisherPush(String exchanges,String key,Object obj)
    {
        System.out.println(&quot;准备发送消息&quot;);
        rabbitTemplate.convertAndSend(exchanges,key,obj);
        System.out.println(&quot;消息发送结束&quot;);
    }
}
</code></pre><h6 id="heading6">接收消息</h6>
<pre><code>@Component
public class RabbitMqConsume {
    /**
     * 手动签收时使用
     * @param info
     * @param headers
     * @param channel
     * @throws Exception
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = &quot;queue&quot;,durable=&quot;true&quot;),
            exchange = @Exchange(name=&quot;exchanges&quot;,durable = &quot;true&quot;,type = &quot;fanout&quot;),
            key = &quot;gba.*&quot;
    ))
    @RabbitHandler
    public void onMessage(@Payload String info, @Headers Map&lt;String,Object&gt; headers, Channel channel)throws Exception{
        //消费消息
        System.out.println(&quot;开始消费消息&quot;);
        System.out.println(&quot;开始消费消息:&quot;+info);
        Long deliveryTag=(Long)headers.get(AmqpHeaders.DELIVERY_TAG);
        //消费完毕手动通知RabbitMQ
        channel.basicAck(deliveryTag,false);
    }

}
</code></pre><h5 id="websocketrabbitmq">WebSocket连接RabbitMQ</h5>
<p><strong>1. RabbitMQ 控制台安装插件</strong></p>
<p>控制台启动插件</p>
<pre><code>rabbitmq-plugins enable rabbitmq_management rabbitmq_web_stomp rabbitmq_stomp rabbitmq_web_stomp_examples
</code></pre><p><strong>2. 代码示例</strong></p>
<pre><code>&lt;html&gt;  
    &lt;head&gt;  
        &lt;title&gt;WebSocket&lt;/title&gt;  
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;  
		&lt;script src=&quot;./js/jquery.js&quot;&gt;&lt;/script&gt;
		&lt;!-- stomp协议的客户端脚本 --&gt;
		&lt;script src=&quot;./js/stomp.js&quot;&gt;&lt;/script&gt;
		&lt;!-- SockJS的客户端脚本 --&gt;
		&lt;script src=&quot;./js/sockjs.js&quot;&gt;&lt;/script&gt;
    &lt;/head&gt;  
    &lt;body&gt;  
    &lt;div id=&quot;main&quot; style=&quot;width: 200px;height: 200px;background-color: antiquewhite;&quot;&gt;
        &lt;div id=&quot;message&quot;&gt;&lt;/div&gt;  
    &lt;/div&gt;  
    &lt;/body&gt; 
     &lt;script type=&quot;text/javascript&quot;&gt;
	/**
	/queue/queuename：使用默认转发器订阅/发布消息，默认由stomp自动创建一个持久化队列 

	/amq/queue/queuename：与/queue/queuename的区别在于队列不由stomp自动进行创建，队列不存在失败 

	/topic/routing_key：通过amq.topic转发器订阅/发布消息，订阅时默认创建一个临时队列，通过routing_key与topic进行绑定 

	/temp-queue/xxx：创建一个临时队列(只能在headers中的属性reply-to中使用)，可用于发送消息后通过临时队列接收回复消息，接收通过client.onreceive 

	/exchange/exchangename/[routing_key]：通过转发器订阅/发布消息，转发器需要手动创建 

	client.subscribe(destination,callback,headers) ：订阅消息 

	client.send(destination,headers,body)：发布消息 

	client.unsubscribe(id)：取消订阅，id为订阅时返回的编号 

	client.onreceive：默认接收回调从临时队列获取消息 
	
	*/
	var ws = new WebSocket('ws://192.168.3.146:15674/ws');
	// 获得Stomp client对象
	var client = Stomp.over(ws);

	// SockJS does not support heart-beat: disable heart-beats
	client.heartbeat.outgoing = 0;
	client.heartbeat.incoming = 0;

	// 定义连接成功回调函数
	var on_connect = function(x) {
		//data.body是接收到的数据（/exchange/交换机名/路由键）
		 client.subscribe(&quot;/exchange/genome-basic-analysisi-exchanges/gba.code&quot;, function(data) {
			var msg = data.body;
			//$(&quot;#message&quot;).append(msg);
			//document.getElementById(&quot;message&quot;).appendChild();
			
			var node=document.createElement(&quot;div&quot;);
				var textnode=document.createTextNode(msg);
				node.appendChild(textnode);
				document.getElementById(&quot;message&quot;).appendChild(node);
			
		});
	};

	// 定义错误时回调函数
	var on_error =  function() {
		console.log('error');
	};

	// 连接RabbitMQ
	client.connect('admin', '123456', on_connect, on_error, '/');
	console.log(&quot;&gt;&gt;&gt;连接上http://192.168.3.146:15674&quot;);
	
	&lt;/script&gt;

 &lt;/html&gt;  
</code></pre><p><strong>3. 说明</strong></p>
<p>发送消息</p>
<pre><code>//参数依次为：目的地，消息头，消息体
client.send('/exchange/交换机名/路由键', {}, &quot;Hello&quot;);
</code></pre><p>订阅某个交换机</p>
<pre><code>//参数依次为：目的地，消息体，消息头
client.subscribe('/exchange/交换机名/路由键', function(frame){}, {});
</code></pre><p>同时还可以以下面的方式创建指定的队列名（本例还增加了持久化）</p>
<pre><code>//参数依次为：目的地，消息头，消息体
client.subscribe('/exchange/wf/wf.warn', function(frame){}, {
	'x-queue-name': 'liuzh',
	'durable': true
});
</code></pre><p>还可以继续给该队列绑定其他路由键：</p>
<pre><code>//参数依次为：目的地，消息头，消息体
client.subscribe('/exchange/wf/wf.error', function(frame){}, {
	'x-queue-name': 'liuzh',
	'durable': true
});
</code></pre><p>除了这里用到的参数外，还支持下面的队列参数：</p>
<ul>
<li>durable (aliased as persistent)：持久化</li>
<li>auto-delete：自动删除</li>
<li>exclusive：独占</li>
</ul>
<p>还额外支持 x- 参数控制死信、队列和消息等：</p>
<ul>
<li>x-dead-letter-exchange</li>
<li>x-dead-letter-routing-key</li>
<li>x-expires</li>
<li>x-message-ttl</li>
<li>x-max-length</li>
<li>x-max-length-bytes</li>
<li>x-overflow</li>
<li>x-max-priority</li>
</ul>
<h5 id="heading7">死信队列和延迟队列</h5>

</div>


  
</article>
      <footer id="main-footer" class="container main_footer">
  

  <div class="container nav foot no-print">
  
<a href="https://lvzongcheng.gitee.io/license">license</a>


  <a class="toplink" href="#">back to top</a>

</div>

  <div class="container credits">
  
<div class="container footline">
  
  code with <!-- raw HTML omitted --><!-- raw HTML omitted -->


</div>


  
<div class="container copyright">
  
  (c) 2015 yourname.


</div>


</div>

</footer>

    </main>
    
<script type="text/javascript">
  (function() {
    
    
    if (window.location.hostname == "localhost")
      return;
    var dsq = document.createElement('script'); dsq.async = true; dsq.type = 'text/javascript';
    dsq.src = '//your_disqus_shortname.disqus.com/count.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  })();
</script>



<script src="/js/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>



    
  </body>
</html>

